package net.zoneland.knowledge.controller;

import static net.zoneland.knowledge.utils.GsonUtils.GSON;
import static net.zoneland.knowledge.utils.GsonUtils.toJson;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.google.common.base.Preconditions;
import com.google.gson.JsonSyntaxException;
import net.zoneland.knowledge.controller.bean.UomUserOrgQueryVo;
import net.zoneland.knowledge.exceptions.DjExceptionCode;
import net.zoneland.knowledge.model.*;
import net.zoneland.knowledge.service.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import com.branchitech.commons.time.biz.IComplexWorkDayHandler;
import com.branchitech.gum.domain.Organization;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Lists;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import net.zoneland.knowledge.config.TalkConfig;
import net.zoneland.knowledge.constant.BizConstant;
import net.zoneland.knowledge.constant.Constants;
import net.zoneland.knowledge.dao.HotQueAndSearchMapper;
import net.zoneland.knowledge.enums.HotQueEnum;
import net.zoneland.knowledge.enums.ResourceTypeEnum;
import net.zoneland.knowledge.utils.GsonUtils;
import net.zoneland.knowledge.utils.LoginUtils;

/**
 * .
 *
 * @author: bcc
 * 2021/5/27
 */
@RestController
@RequestMapping("/api")
public class ApiController {

    private static final Logger LOGGER = LoggerFactory.getLogger(ApiController.class);

    /**
     * guava缓存，获取内存.
     */
    private Cache<String, List<String>> holidayCache = CacheBuilder.newBuilder().expireAfterWrite(12, TimeUnit.HOURS).build();

    @Autowired
    private IComplexWorkDayHandler iComplexWorkDayHandler;

    @Autowired
    private TalkConfig talkConfig;

    @Autowired
    private ApiService apiService;

    @Autowired
    private ResourceService resourceService;

    @Autowired
    private QaRecordsV2Service qaRecordsV2Service;

    @Autowired
    private QaBankService qaBankService;

    @Autowired
    private QaSuggestService qaSuggestService;

    @Autowired
    private DictItemService dictItemService;

    @Autowired
    private FavoriteService favoriteService;

    @Autowired
    private QaSatisfactionService qaSatisfactionService;

    @Autowired
    private HotQueAndSearchMapper hotQueAndSearchMapper;

    @Autowired
    private UserService userService;

    /**
     * 党员/党组织业务接口.
     */
    @Autowired
    private PartyService partyService;

    /**
     * 科目信息接口.
     */
    @Autowired
    private SubjectLevelService subjectLevelService;

    /**
     * 智能导航类型的key
     */
    private static final String STRING_KEY_ZNDH = "ZNDH";

    /**
     * 失败标志.
     */
    private static final String ZERO = "0";

    /**
     * 获取当前登录用户信息.
     *
     * @param request  http请求
     * @param response http响应
     * @return 结果
     */
    @ResponseBody
    @RequestMapping(value = "/test", method = RequestMethod.GET, produces = "text/html;charset=UTF-8")
    public String test(final HttpServletRequest request, final HttpServletResponse response) {
        String token = request.getHeader(Constants.TOKEN_NAME);
        LoginUserPojo loginUserPojo = LoginUtils.getCurrentUserByToken(token);
        return toJson(loginUserPojo);
    }

    /**
     * 获取当前登录用户信息.
     *
     * @param request  http请求
     * @param response http响应
     * @return 结果
     */
    @ResponseBody
    @RequestMapping(value = "/getUserInfo.htm", method = RequestMethod.GET, produces = "text/html;charset=UTF-8")
    public String getUserInfo(final HttpServletRequest request, final HttpServletResponse response) {
        final ResponseResult result = new ResponseResult();
        try {
            final LoginUserPojo user = LoginUtils.getCurrentUserByToken(request.getHeader(Constants.TOKEN_NAME));
            if (null != user) {
                final String employeeNumber = user.getUserIdCard();
                //准备用户信息
                if (LoginUtils.isEmployee(employeeNumber)) {
                    user.setImageUrl(talkConfig.getHrmisImage() + employeeNumber);
                } else {
                    user.setImageUrl(request.getScheme() + "://" + request.getServerName()
                            + ":" + request.getServerPort() + request.getContextPath() + "/static/images/user.png");
                }
                result.setData(user);
            } else {
                result.setResult(ZERO);
                result.setMessage("获取token关联的用户信息为空！");
            }
        } catch (Exception e) {
            result.setResult(ZERO);
            result.setMessage("获取当前登录用户失败！");
            LOGGER.error(">>>>>>>>>>>>>获取当前登录用户失败：", e);
        }
        return toJson(result);
    }

    @ResponseBody
    @RequestMapping(value = "/getRoles.htm", method = RequestMethod.GET, produces = "text/html;charset=UTF-8")
    public String getRoles(final HttpServletRequest request, final HttpServletResponse response) {
        ResponseResult result = new ResponseResult();
        try {
            List<String> currentUserRoles = LoginUtils.getCurrentUserRoleByToken(request.getHeader(Constants.TOKEN_NAME));
            result.setData(currentUserRoles);
        } catch (Exception e) {
            result.setResult(ZERO);
            result.setMessage("获取当前登录用户失败！");
            LOGGER.error(">>>>>>>>>>>>>获取当前登录用户失败：", e);
        }
        return toJson(result);
    }

    /**
     * 获取当前登录用户权限信息.
     *
     * @param request  http请求
     * @param response http响应
     * @return 结果
     */
    @ResponseBody
    @RequestMapping(value = "/getUserAuth.htm", method = RequestMethod.GET, produces = "text/html;charset=UTF-8")
    public String getUserAuth(final HttpServletRequest request, final HttpServletResponse response) {
        ResponseResult result = new ResponseResult();
        try {
            List<Resource> menuList = new ArrayList<Resource>();
            List<TreeNode<Resource>> nodeList = LoginUtils.geCurrentResByToken(request.getHeader(Constants.TOKEN_NAME));
            if (CollectionUtils.isNotEmpty(nodeList)) {
                nodeList.stream().filter(nodeObj -> Constants.RESOURCE_ROOT_MYJOB.equals(nodeObj.getId()))
                        .forEach(nodeObj -> {
                                    //只需要我的工作下的菜单模块
                                    List<TreeNode<Resource>> myJobNodeList = nodeObj.getChildren();
                                    if (CollectionUtils.isNotEmpty(myJobNodeList)) {
                                        //是菜单并且配置了Icon的才是需要给前端使用的
                                        myJobNodeList.stream().filter(resourceTreeNode ->
                                                ResourceTypeEnum.MENU.getValue().equals(resourceTreeNode.getData().getResourceType())
                                                        && StringUtils.isNotBlank(resourceTreeNode.getData().getIcon())
                                        ).forEach(resourceTreeNode -> {
                                            //给前端显示的url需要是全链接，方便直接从聊天对话页面调到后台应用
                                            Resource resource = resourceTreeNode.getData();
                                            resource.setScriptUrls(new StringBuilder().append(request.getScheme()).append("://")
                                                    .append(request.getServerName()).append(":").append(request.getServerPort())
                                                    .append(request.getContextPath()).append(resource.getScriptUrls()).toString());
                                            menuList.add(resource);
                                        });
                                    }
                                }
                        );
                //默认添加我的推送
                Resource resource = resourceService.getById(Constants.RESOURCE_MYPUSH);
                if (null != resource) {
                    menuList.add(resource);
                }
                //按orders顺序显示
                List<Resource> newMenuList = menuList.stream().sorted(Comparator.comparing(Resource::getOrders))
                        .collect(Collectors.toList());
                result.setData(newMenuList);
            }
        } catch (Exception e) {
            result.setResult(ZERO);
            result.setMessage("获取当前登录用户失败！");
            LOGGER.error(">>>>>>>>>>>>>获取当前登录用户失败：", e);
        }
        return GsonUtils.toJson(result);
    }

    /**
     * 获取机器人名称.
     *
     * @param request  http请求
     * @param response http响应
     * @param session  http的Session
     * @return 结果
     */
    @ResponseBody
    @RequestMapping(value = "/getRobotInfo.htm", method = RequestMethod.GET, produces = "text/html;charset=UTF-8")
    public String getRobotInfo(final HttpServletRequest request, final HttpServletResponse response, final HttpSession session) {
        ResponseResult result = new ResponseResult();
        try {
            //系统管理员
            LoginUserPojo loginUser = LoginUtils.getCurrentUserByToken(request.getHeader(Constants.TOKEN_NAME));
            RobotInfo robotInfo = apiService.getRobotInfo(loginUser, true);
            session.setAttribute(BizConstant.REPLACE_ROBOT_NAME, robotInfo.getRobotName());
            result.setData(robotInfo);
        } catch (Exception e) {
            result.setResult(ZERO);
            result.setMessage("获取机器人信息失败！");
            LOGGER.error(">>>>>>>>>>>>>获取机器人信息失败：", e);
        }
        return GsonUtils.toJson(result);
    }

    /**
     * 获取热点问题排行榜.
     *
     * @param request  http请求
     * @param category 分类
     * @param response http响应
     * @return 结果
     */
    @ResponseBody
    @RequestMapping(value = "/getHotQuestions.htm", method = RequestMethod.GET, produces = "text/html;charset=UTF-8")
    public String getHotQuestions(final HttpServletRequest request, final String category, final HttpServletResponse response) {
        ResponseResult result = new ResponseResult();
        try {
            LoginUserPojo loginUser = LoginUtils.getCurrentUserByToken(request.getHeader(Constants.TOKEN_NAME));
            final HotQueAndSearchExample example = new HotQueAndSearchExample();
            final HotQueAndSearchExample.Criteria criteria = example.createCriteria()
                .andConfigurationTypeEqualTo(HotQueEnum.HOT_QUESTION.getName())
                .andOrOrgDn(loginUser.getCompanyDN());
            if(StringUtils.isNotBlank(category)) {
                criteria.andCategoryEqualTo(category);
            }
            example.setOrderByClause(" sort asc");
            final List<HotQueAndSearch> hotQueAndSearches = hotQueAndSearchMapper.selectByExample(example);
            int count = 0;
            List<StatisticsBo> statisticsBos = new ArrayList<>();
            for (HotQueAndSearch hotQueAndSearch: hotQueAndSearches) {
                    StatisticsBo statisticsBo = new StatisticsBo();
                    statisticsBo.setId(String.valueOf(count+1));
                    statisticsBo.setQueName(hotQueAndSearch.getQueName());
                    count++;
                statisticsBos.add(statisticsBo);
            }
            result.setData(statisticsBos);
        } catch (Exception e) {
            result.setResult(ZERO);
            result.setMessage("getHotQuestions fail！");
            LOGGER.error(">>>>>>>>>>>>>getHotQuestions fail：", e);
        }
        return GsonUtils.toJson(result);
    }

    /**
     * 获取搜索排行榜.
     *
     * @param request  http请求
     * @param response http响应
     * @return 结果
     */
    @ResponseBody
    @RequestMapping(value = "/getSearchQuestions.htm", method = RequestMethod.GET, produces = "text/html;charset=UTF-8")
    public String getSearchQuestions(final HttpServletRequest request, final String category, final HttpServletResponse response) {
        ResponseResult result = new ResponseResult();
        try {
            LoginUserPojo loginUser = LoginUtils.getCurrentUserByToken(request.getHeader(Constants.TOKEN_NAME));
            final HotQueAndSearchExample example = new HotQueAndSearchExample();
            final HotQueAndSearchExample.Criteria criteria = example.createCriteria()
                .andConfigurationTypeEqualTo(HotQueEnum.SEARCH_RANK.getName())
                .andOrOrgDn(loginUser.getCompanyDN());
            if(StringUtils.isNotBlank(category)) {
                criteria.andCategoryEqualTo(category);
            }
            example.setOrderByClause(" sort asc");
            final List<HotQueAndSearch> hotQueAndSearches = hotQueAndSearchMapper.selectByExample(example);
            int count = 0;
            List<StatisticsBo> statisticsBos = new ArrayList<>();
            for (HotQueAndSearch hotQueAndSearch: hotQueAndSearches) {
                StatisticsBo statisticsBo = new StatisticsBo();
                statisticsBo.setId(String.valueOf(count+1));
                statisticsBo.setQueName(hotQueAndSearch.getQueName());
                count++;
                statisticsBos.add(statisticsBo);
            }
            result.setData(statisticsBos);
        } catch (Exception e) {
            result.setResult(ZERO);
            result.setMessage("getSearchQuestions fail！");
            LOGGER.error(">>>>>>>>>>>>>getSearchQuestions fail：", e);
        }
        return GsonUtils.toJson(result);
    }

    /**
     * 下载文件.
     *
     * @param request  http请求
     * @param fileName 文件名
     * @param piid     流程id
     * @param qaBankId 题库id
     * @param fileId   文件id
     * @param type     类型
     * @param response 响应
     */
    @RequestMapping(value = "downloadFile.ajax/{fileName:.+}*", method = RequestMethod.GET)
    public void downloadFile(final HttpServletRequest request, @PathVariable final String fileName, final String piid,
                             final String qaBankId, final String fileId, final String type, final HttpServletResponse response) {
        try {
            //获取将要插入答案所属文件的题
            List<QaBankWithBLOBs> qaBankList = qaBankService.queryByPiidAndBankId(piid, qaBankId);
            if (qaBankList.size() > 0) {
                QaBankWithBLOBs qaBank = qaBankList.get(0);
                Map<String, Map<String, String>> ansContentFile = GSON.fromJson(new String(qaBank.getAnsContentFile(),
                        StandardCharsets.ISO_8859_1), Map.class);
                Map<String, Map<String, String>> ansContentName = GSON.fromJson(qaBank.getAnsContentName(), Map.class);
                Map<String, String> ansContentNameMap = ansContentName.get(type);

                String file = ansContentFile.get(type).get(fileId);
                // 非常重要
                response.reset();
                String name = ansContentNameMap.get(fileId);
                if ("file".equals(type)) {
                    response.setContentType("application/x-msdownload");
                    response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(name, "UTF-8"));
                }
                byte[] buf = file.getBytes(StandardCharsets.ISO_8859_1);
                OutputStream out = response.getOutputStream();
                out.write(buf, 0, buf.length);
                out.close();
            } else {
                response.setContentType("text/plain; charset=utf-8");
                response.getWriter().write("文件下载失败");
            }
        } catch (Exception ex) {
            LOGGER.error("下载异常", ex);
        }
    }

    /**
     * 答案评论，赞或踩.
     *
     * @param request  http请求
     * @param response http响应
     * @return 结果
     */
    @ResponseBody
    @RequestMapping(value = "/comment.htm", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    public String comment(final HttpServletRequest request, final HttpServletResponse response) {
        ResponseResult result = new ResponseResult();
        try {
            String type = request.getParameter("type");
            String recordId = request.getParameter("commnetId");
            if (StringUtils.isNotBlank(type) && StringUtils.isNotBlank(recordId)
                    && ((ZERO.equals(type)) || ("1".equals(type)))) {
                QaRecordsV2 qaRecords = qaRecordsV2Service.getById(recordId);
                if (null != qaRecords) {
                    qaRecords.setPraise(Integer.parseInt(type));
                    qaRecordsV2Service.update(qaRecords);
                } else {
                    result.setResult(ZERO);
                    result.setMessage("评论的问答信息不存在！");
                }
            } else {
                result.setResult(ZERO);
                result.setMessage("输入信息格式错误！");
            }
        } catch (Exception e) {
            result.setResult(ZERO);
            result.setMessage("答案评论失败！");
            LOGGER.error(">>>>>>>>>>>>>答案评论失败", e);
        }
        return toJson(result);
    }

    /**
     * 优化建议收集.
     *
     * @param request  http请求
     * @param question 问题
     * @param title    标题
     * @param content  内容
     * @return 结果
     */
    @ResponseBody
    @RequestMapping(value = "/addOptimizeAdvise.htm", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    public String addOptimizeAdvise(final HttpServletRequest request, final String question,
                                    final String title, final String content) {
        ResponseResult result = new ResponseResult();
        try {
            if (StringUtils.isBlank(question) || StringUtils.isBlank(content)) {
                result.setResult(ZERO);
                result.setMessage("必填信息缺失！");
                return toJson(result);
            }
            //获取当前登录人信息
            LoginUserPojo user = LoginUtils.getCurrentUserByToken(request.getHeader(Constants.TOKEN_NAME));
            if (null == user) {
                result.setResult(ZERO);
                result.setMessage("登录信息失效！");
                return toJson(result);
            }
            QaSuggest qaSuggest = new QaSuggest();
            qaSuggest.setId(UUID.randomUUID().toString());
            qaSuggest.setQuestionType(question);
            qaSuggest.setTitle(title);
            qaSuggest.setContents(content);
            qaSuggest.setReqId(user.getUserID());
            qaSuggest.setReqName(user.getUserName());
            final Organization companyByCode = userService.getCompanyByCode(user.getCompanyDN());
            if(null != companyByCode) {
                qaSuggest.setCmpName(companyByCode.getOrgName());
            }
            qaSuggest.setDeptDn(user.getDepartmentDN());
            qaSuggest.setCreateTime(new Date());
            qaSuggestService.save(qaSuggest);
        } catch (Exception e) {
            result.setResult(ZERO);
            result.setMessage("保存优化建议意见失败！");
            LOGGER.error(">>>>>>>>>>>>>保存优化建议意见失败", e);
        }
        return toJson(result);
    }

    /**
     * 获取后台字段配置.
     *
     * @param parentId 字典id
     * @return 结果
     */
    @ResponseBody
    @GetMapping(value = "/getDictInfos", produces = "text/html;charset=UTF-8")
    public String getDictInfos(final String parentId) {
        ResponseResult result = new ResponseResult();
        try {
            result.setData(dictItemService.findDictByParentId(parentId));
        } catch (Exception e) {
            result.setResult(ZERO);
            result.setMessage("getDictInfos fail！");
            LOGGER.error(">>>>>>>>>>>>>getDictInfos fail：", e);
        }
        return GsonUtils.toJson(result);
    }

    /**
     * 获取节假日.
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 结果
     */
    @ResponseBody
    @GetMapping(value = "/getHolidays", produces = "text/html;charset=UTF-8")
    public String getHolidays(final String startDate, final String endDate) {
        ResponseResult result = new ResponseResult();
        try {
            final List<String> days = holidayCache.get(startDate + endDate, () -> {
                final List<String> holidaysFromHolidayMgr = getHolidaysFromHolidayMgr(startDate, endDate);
                if (null != holidaysFromHolidayMgr) {
                    return holidaysFromHolidayMgr;
                }
                return new ArrayList();
            });
            result.setData(days);
        } catch (Exception e) {
            result.setResult(ZERO);
            result.setMessage("getHolidays fail！");
            LOGGER.error(">>>>>>>>>>>>>getHolidays fail：", e);
        }
        return GsonUtils.toJson(result);
    }

    /**
     * 获取节假日列表.
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 结果
     * @throws ParseException 解析异常
     */
    private List<String> getHolidaysFromHolidayMgr(final String startDate, final String endDate) throws ParseException {
        //目前只有根据月份查询节假日的接口
        //先判断startDate 和 endDate是否同一月份的
        String heng = "-";
        final String startDateTmp = startDate.replaceAll(heng, "");
        final String endDateTmp = endDate.replaceAll(heng, "");
        final String startMonth = startDateTmp.substring(0, 6);
        final String endMonth = endDateTmp.substring(0, 6);
        final Set<String> allHolidays = new HashSet<>();
        allHolidays.addAll(getAllHolidayByMonth(startMonth));
        final Integer startDateInt = Integer.valueOf(startDateTmp);
        final Integer endDateInt = Integer.valueOf(endDateTmp);

        int tmpdate = Integer.valueOf(startMonth);
        int endMonthInt = Integer.valueOf(endMonth);
        while (tmpdate < endMonthInt) {
            tmpdate = tmpdate % 100 == 12 ? tmpdate + 89 : tmpdate + 1;
            allHolidays.addAll(getAllHolidayByMonth("" + tmpdate));
        }
        return allHolidays.stream().
                filter(item -> Integer.valueOf(item) >= startDateInt
                        && Integer.valueOf(item) <= endDateInt).
                map(item -> item.substring(0, 4) + heng + item.substring(4, 6) + heng + item.substring(6, 8))
                .sorted().collect(Collectors.toList());
    }

    private Set<String> getAllHolidayByMonth(final String month) throws ParseException {
        final Map<String, Set<String>> holidayByMonth = iComplexWorkDayHandler.getHolidayByMonth(month);
        return holidayByMonth.values().stream().flatMap(Set::stream).collect(Collectors.toSet());
    }

    /**
     * 添加收藏.
     *
     * @param request      http请求
     * @param category     分类
     * @param type         （1：收藏、0：取消收藏）
     * @param esQuestionId es题库id
     * @param titleType 收藏内容标题分类
     * @return 结果
     */
    @ResponseBody
    @GetMapping("/addFavorite")
    public String addFavorite(final HttpServletRequest request, final String category,
                              final Integer type, final String esQuestionId, final String titleType) {
        ResponseResult result = new ResponseResult();
        //获取当前登录人信息
        final LoginUserPojo user = LoginUtils.getCurrentUserByToken(request.getHeader(Constants.TOKEN_NAME));
        try {
            final String msg = checkFavoriteparam(esQuestionId, category, type, titleType);
            if (StringUtils.isNotBlank(msg)) {
                result.setResult(ZERO);
                result.setMessage(msg);
                return GsonUtils.toJson(result);
            }
            final String res = favoriteService.addFavorite(user, esQuestionId, type, category, titleType);
            if (StringUtils.isNotBlank(res)) {
                result.setResult(ZERO);
                result.setMessage(res);
                return GsonUtils.toJson(result);
            }
        } catch (Exception e) {
            result.setResult(ZERO);
            result.setMessage("addFavorite fail！");
            LOGGER.error(">>>>>>>>>>>>>addFavorite fail：", e);
        }
        return GsonUtils.toJson(result);
    }

    /**
     * 验证ID格式.
     *
     * @param esQuestionId es问题id
     * @param category     分类
     * @param type         类型
     * @return 结果
     */
    private String checkFavoriteparam(final String esQuestionId, final String category, final Integer type, final String titleType) {
        if (null == category
                || null == type || !Lists.newArrayList(1, 0).contains(type)
                || StringUtils.isBlank(esQuestionId) || StringUtils.isBlank(titleType)) {
            return "参数不能正确";
        }

        if (StringUtils.isEmpty(esQuestionId)) {
            return "参数不能正确";
        }

        return null;
    }

    /**
     * 记录满意度情况.
     *
     * @param request  http请求
     * @param response http响应
     * @return 结果
     **/
    @ResponseBody
    @RequestMapping(value = "/addSatisfaction.htm", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    public String addSatisfaction(final HttpServletRequest request, final HttpServletResponse response) {
        ResponseResult result = new ResponseResult();
        final String type = request.getParameter("type");
        final String queContent = request.getParameter("queContent");
        final String talkSessionId = request.getParameter("talkSessionId");
        Map<String, Object> map = new HashMap<>();
        map.put("sessionId", talkSessionId);
        final Optional<List<QaSatisfaction>> qaSatisfactions = Optional
                .ofNullable(qaSatisfactionService.queryBySessionId(talkSessionId));
        Optional.ofNullable(qaSatisfactions).ifPresent(it -> {
            List<QaSatisfaction> qaSatisfactionsList = it.orElseGet(null);
            if (CollectionUtils.isNotEmpty(qaSatisfactionsList)) {
                qaSatisfactionsList.stream().findFirst()
                    .filter(x -> ZERO.equals(type)).ifPresent(x -> {
                        x.setStatus(0);
                        x.setQueName(queContent);
                        try {
                            qaSatisfactionService.update(x);
                        } catch (Exception e) {
                            result.setResult(ZERO);
                            result.setMessage("满意度更新失败！");
                            LOGGER.error(">>>>>>>>>>>>>满意度更新失败：", e);
                        }
                    });
            } else {
                LoginUserPojo user = LoginUtils.getCurrentUserByToken(request.getHeader(Constants.TOKEN_NAME));
                QaSatisfaction qaSatisfaction = new QaSatisfaction();
                qaSatisfaction.setId(UUID.randomUUID().toString());
                qaSatisfaction.setSessionId(talkSessionId);
                final String reqId = Optional.ofNullable(user.getUserIdCard())
                    .filter(StringUtils::isNotBlank)
                    .orElse(user.getUserID());
                qaSatisfaction.setReqId(reqId);
                qaSatisfaction.setReqName(user.getUserName());
                qaSatisfaction.setCmpDn(user.getCompanyDN());
                qaSatisfaction.setDeptDn(user.getDepartmentDN());
                if (ZERO.equals(type)) {
                    if (StringUtils.isBlank(queContent)) {
                        qaSatisfaction.setStatus(1);
                        qaSatisfaction.setQueName(BizConstant.NO_OPINION_SATISFY_CONTENT);
                    } else {
                        qaSatisfaction.setStatus(0);
                        qaSatisfaction.setQueName(queContent);
                    }
                } else {
                    qaSatisfaction.setStatus(1);
                    qaSatisfaction.setQueName(queContent);
                }
//                qaSatisfaction.setQueName(queContent);
                qaSatisfaction.setCreateTime(new Date());
                try {
                    //先保存数据
                    qaSatisfactionService.save(qaSatisfaction);
                    //再启动流程
                    qaSatisfactionService.update(qaSatisfaction);
                } catch (Exception e) {
                    result.setResult(ZERO);
                    result.setMessage("满意度更新失败！");
                    LOGGER.error(">>>>>>>>>>>>>满意度更新失败：", e);
                }
            }
        });

        return toJson(result);
    }


    /**
     * 获取数据分类.
     *
     * @return 结果
     */
    @ResponseBody
    @GetMapping(value = "/getDataCategory", produces = "application/json;charset=UTF-8")
    public ResponseResult getDataCategory() {
        try {
            // 获取数据分类
            final List<DataCategory> datas = ListUtils.emptyIfNull(apiService.getDataCategory());
            // 用户要求过滤掉智能导航"ZNDH"的数据
            return new ResponseResult(datas.stream()
                    .filter(data -> !StringUtils.equals(data.getKey(), STRING_KEY_ZNDH))
                    .collect(Collectors.toList()));
        } catch (final JsonSyntaxException | NullPointerException e) {
            final ResponseResult result = new ResponseResult();
            result.setResult(ResponseResult.FAILED_RESULT);
            result.setMessage("获取数据分类失败！");
            LOGGER.error(result.getMessage(), e);
            return result;
        }
    }

    /**
     * 获取数据分类.
     *
     * @return 结果
     */
    @ResponseBody
    @GetMapping(value = "/getQuickNav", produces = "text/html;charset=UTF-8")
    public String getQuickNav() {
        ResponseResult result = new ResponseResult();
        try {
            final List<QuickNav> quickNavs = apiService.getQuickNav();
            Map<String,List<QuickNav>> map = new HashMap<>();
            if(CollectionUtils.isNotEmpty(quickNavs)){
                for(QuickNav quickNav:quickNavs) {
                    List<QuickNav> list = map.get(quickNav.getCategory());
                    if(list == null) {
                        list = new ArrayList<>();
                    }
                    list.add(quickNav);
                    map.put(quickNav.getCategory(), list);
                }
            }
            result.setData(map);
        } catch (Exception e) {
            result.setResult(ZERO);
            result.setMessage("getQuickNav fail！");
            LOGGER.error(">>>>>>>>>>>>>getQuickNav fail：", e);
        }
        return GsonUtils.toJson(result);
    }

    @ResponseBody
    @RequestMapping(value = "/queryNextSubjects", method = RequestMethod.POST)
    public String queryNextSubjects(final HttpServletRequest request, final HttpServletResponse response, @RequestBody final SubjectLevel subjectLevel) {
        Preconditions.checkArgument(Objects.nonNull(subjectLevel), DjExceptionCode.DJ_OBJ_NULL);
        final ResponseResult result = new ResponseResult();
        try {
            final List<SubjectLevel> subjectLevelList = subjectLevelService.queryByLevel(subjectLevel.getSubjectName(), subjectLevel.getCategory());
            result.setData(subjectLevelList);
        } catch (Exception e) {
            result.setResult(ZERO);
            result.setMessage("queryNextSubjects fail！");
            LOGGER.error(">>>>>>>>>>>>>queryNextSubjects fail：,subjectLevel:{}", subjectLevel, e);
        }
        return GsonUtils.toJson(result);
    }

    @ResponseBody
    @RequestMapping(value = "/queryQaBankBySubject", method = RequestMethod.POST)
    public String queryQaBankBySubject(final HttpServletRequest request, final HttpServletResponse response, @RequestBody final QaBank qaBank) {
        Preconditions.checkArgument(Objects.nonNull(qaBank), DjExceptionCode.DJ_OBJ_NULL);
        final ResponseResult result = new ResponseResult();
        try {
            final LoginUserPojo loginUser = LoginUtils.getCurrentUserByToken(request.getHeader(Constants.TOKEN_NAME));
            if(Objects.nonNull(loginUser)){
                qaBank.setOrgDn(loginUser.getCompanyDN());
            }
            final List<String> currentUserRole = LoginUtils.getCurrentUserRoleByToken(request.getHeader(Constants.TOKEN_NAME));
            result.setData(qaBankService.queryBySubject(qaBank, loginUser, currentUserRole));
        } catch (Exception e) {
            result.setResult(ZERO);
            result.setMessage("queryQaBankBySubject fail！");
            LOGGER.error(">>>>>>>>>>>>>queryQaBankBySubject fail：,qaBank:{}", qaBank, e);
        }
        return GsonUtils.toJson(result);
    }

    /**
     * 查询收藏内容
     * @param request request
     * @return 收藏内容列表
     */
    @ResponseBody
    @GetMapping("/searchFavorite")
    public String searchFavorite(final HttpServletRequest request) {
        //获取当前登录人信息
        final LoginUserPojo user = LoginUtils.getCurrentUserByToken(request.getHeader(Constants.TOKEN_NAME));
        ResponseResult result = new ResponseResult();
        try {
            result.setData(favoriteService.searchFavorite(user));
        } catch (Exception e) {
            result.setResult(ZERO);
            result.setMessage("getDataCategory fail！");
            LOGGER.error(">>>>>>>>>>>>>searchFavorite fail：{}", e.getMessage());
        }
        return GsonUtils.toJson(result);
    }


    /**
     * 查询人员手机号信息.
     * @param voList 查询参数.
     * @return 人员手机号信息
     */
    @ResponseBody
    @RequestMapping(value = "/queryUserMobiles", method = RequestMethod.POST)
    public ResponseResult queryUserMobiles(@RequestBody final List<UomUserOrgQueryVo> voList) {
        return new ResponseResult(partyService.searchMobileListByCondition(voList));
    }

}
